#include "test_sm_qt.h"

QVariantMap gTestStateMachine;

void prepareQtStateMachine( )
{
    gTestStateMachine.insert( "name","s1" );

    // gTestStateMachine.insert( "execMode", "RunSync" );           // Parent-Child(SYNC) Children(SYNC) OK
    // gTestStateMachine.insert( "execMode", "RunWithParent" );     // Parent-Child(SYNC) Children(ASYNC) cannot test now
    // gTestStateMachine.insert( "execMode", "RunBatchAsync" );     // Parent-Child(ASYNC) Children(SYNC) OK
    gTestStateMachine.insert( "execMode", "RunEachAsync" );      // Parent-Child(ASYNC) Children(ASYNC) F
    
    gTestStateMachine.insert( "guid", "{2d5503ca-52ed-4746-9807-fccd23da7e69}" );
        QVariantList states;
            QVariantMap state;
            state.insert( "name","EXCEPTIONS" );
            state.insert( "heartbeatrate",0);
            state.insert( "heartbeats",0);
                QVariantList todolist;
                    QVariantList todo01;
                    todo01 << QVariant( "EV_SYS_TERMINATE" ) << QVariant( "exit" ) << QVariant( "" );
                    //todo01 << QVariant( ) << QVariant( ) << QVariant( );
                todolist << QVariant(todo01);
            state.insert( "todolist", todolist);

        states << QVariant(state);
            QVariantMap state1;
            state1.insert( "name","OUTSIDE" );
            state1.insert( "heartbeatrate",1);
            state1.insert( "heartbeats",1);
                QVariantList todolist1;
                    QVariantList todo11,todo12, todo13, todo14 ;
                    todo11 << QVariant( "EV_SYS_ON_ENTRY" ) << QVariant( "doAction1" ) << QVariant( "" );
                    todo12 << QVariant( "EV_INT_MOUSE_INSIDE" ) << QVariant( "doAction1" ) << QVariant( "" );
                    todo13 << QVariant( "EV_SYS_HEARTBEAT" ) << QVariant( "doAction3" ) << QVariant( "" );
                    todo14 << QVariant( "EV_SYS_LAST_HEARTBEAT" ) << QVariant( "doAction4" ) << QVariant( "DUMMY" );
                
                todolist1 << QVariant(todo11) << QVariant(todo12) << QVariant(todo13) << QVariant(todo14);
            state1.insert( "todolist", todolist1);

        states << QVariant(state1);
            QVariantMap state2;
            state2.insert( "name","INSIDE" );
            state2.insert( "heartbeatrate",0);
            state2.insert( "heartbeats",0);
                QVariantList todolist2;
                    QVariantList todo21, todo22, todo23;
                    todo21 << QVariant( "EV_INT_MOUSE_OUTSIDE" ) << QVariant( "" ) << QVariant( "" );
                    todo22 << QVariant( "EV_INT_MOUSE_OUTSIDE" ) << QVariant( "doAction2" ) << QVariant( "OUTSIDE" );
                    todo23 << QVariant( "EV_SYS_ON_ENTRY" ) << QVariant( "doAction2" ) << QVariant( "" );
                todolist2 << QVariant(todo21) << QVariant(todo22) << QVariant(todo23);

            state2.insert( "todolist", todolist2);
        states << QVariant(state2);

            QVariantMap state3;
            state3.insert( "name","DUMMY" );
            state3.insert( "heartbeatrate",1);
            state3.insert( "heartbeats",1);
                QVariantList todolist3;
                    QVariantList todo30, todo31, todo32, todo33, todo34;
                    todo30 << QVariant( "EV_SYS_ON_ENTRY" ) << QVariant( "doAction1" ) << QVariant( "" );
                    todo31 << QVariant( "EV_INT_MOUSE_INSIDE" ) << QVariant( "doAction1" ) << QVariant( "INSIDE" );
                    todo32 << QVariant( "EV_INT_MOUSE_OUTSIDE" ) << QVariant( "doAction2" ) << QVariant( "OUTSIDE" );
                    todo33 << QVariant( "EV_SYS_HEARTBEAT" ) << QVariant( "doAction3" ) << QVariant( "" );
                    //todo34 << QVariant( "EV_SYS_LAST_HEARTBEAT" ) << QVariant( "exit" ) << QVariant( "" );
                    todo34 << QVariant( "EV_SYS_LAST_HEARTBEAT" ) << QVariant( "" ) << QVariant( "" );
                todolist3 << QVariant(todo30) << QVariant(todo31) << QVariant(todo32) << QVariant(todo33) << QVariant(todo34);
            state3.insert( "todolist", todolist3);
        states << QVariant(state3);
    gTestStateMachine.insert( "states",states);
}

OsMutex MyThread::m_cr( 0 );
Queue gQueue;

void MyThread::run( )
{
    Object* event;
    for( int i = 0; i < 100; i++ ) 
    {
        msleep( 10 );
        event = NEW Object;
        m_cr.enter( );
        gQueue.push(event);
        m_cr.leave( );
        event->release_ref( );
    }
}

void test_QtStateMachine( )
{
    prepareQtStateMachine( );

    const int amount = 100;
    MyStateMachine* first = NULL;
    List all;
    for( int i = 0; i < amount; i++ ) 
    {
        Object* context = NEW Object( );
        MyStateMachine* m = NEW MyStateMachine( );
        if ( !first ) 
        {
            m->createQt( gTestStateMachine, context );
            first = m;
        }
        else
        {
            m->createQt( first, context );
        }
        context->release_ref( );
        all.attach_last( m );
    }
    // Start all siblings state machines 
    first->startQt( );

    Engine::terminate( );

    for( HIterator< StateMachine* > i( all.get_first( ) ); *i; i++ )
    {
        i->release_ref( );
    }
    all.clear( );

    //////////////////////////////
    SEA_MEM_LEAKS( );
}
